package see.battle.gui;

import see.battle.drawer.AndroidDrawer.CanvasSetter;
import see.battle.object.ObjectPool.DrawProcessor;
import see.battle.object.ObjectPool.FireProcessor;
import see.battle.object.ObjectPool.MoveOcularProcessor;
import android.content.Context;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback {
  private float _X;
  private float _Y;
  private boolean _movingOcular = false;
  private boolean _surfaceIsAvailable = false;
  private int _widthInPx;
  private int _heightInPx;
  private FireProcessor _fireProcessor;
  private MoveOcularProcessor _moveOcularProcessor;
  private DrawProcessor _drawProcessor;
  private CanvasSetter _canvasSetter;

  public GameView(Context context) {
    super(context);
    getHolder().addCallback(this);
    setFocusable(true);
  }

  public void set_widthInPx(int widthInPx) {
    _widthInPx = widthInPx;
  }

  public void set_heightInPx(int heightInPx) {
    _heightInPx = heightInPx;
  }

  public void set_fireProcessor(FireProcessor fireProcessor) {
    _fireProcessor = fireProcessor;
  }

  public void set_moveOcularProcessor(MoveOcularProcessor moveOcularProcessor) {
    _moveOcularProcessor = moveOcularProcessor;
  }

  public void set_drawProcessor(DrawProcessor drawProcessor) {
    _drawProcessor = drawProcessor;
  }

  public void set_canvasSetter(CanvasSetter canvasSetter) {
    _canvasSetter = canvasSetter;
  }

  public boolean is_surfaceIsAvailable() {
    return _surfaceIsAvailable;
  }

  public boolean onTouchEvent(MotionEvent e) {
    if (e.getActionMasked() == MotionEvent.ACTION_DOWN) {
      _X = e.getX();
      _Y = e.getY();
      _movingOcular = true;
      try {
        if (_fireProcessor != null) {
          _fireProcessor.setX(_X / _widthInPx);
          _fireProcessor.setY(_Y / _heightInPx);
          _fireProcessor.call();
        }
      } catch (Exception e1) {
        e1.printStackTrace();
      }
    } else if (e.getActionMasked() == MotionEvent.ACTION_MOVE) {
      if (_movingOcular) {
        float dx = (_X - e.getX()) / _widthInPx;
        if (_moveOcularProcessor != null) {
          _moveOcularProcessor.setDx(dx);
          try {
            _moveOcularProcessor.call();
          } catch (Exception e1) {
            e1.printStackTrace();
          }
        }
        _X = e.getX();
      }
    } else if (e.getActionMasked() == MotionEvent.ACTION_UP) {
      _movingOcular = false;
    }
    return true;
  }
  
  public void redraw() {
    Canvas c = null;
    SurfaceHolder surfaceHolder = getHolder();
    try {          
      c = surfaceHolder.lockCanvas();
      synchronized (surfaceHolder) {
        onDraw(c);
      }
    } finally {
      if (c != null) {
        surfaceHolder.unlockCanvasAndPost(c);
      }
    }
  }

  //@Override
  public void onDraw(Canvas canvas) {
    if (_canvasSetter != null) {
      _canvasSetter.setCanvas(canvas);
      try {
        _canvasSetter.call();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    if (_drawProcessor != null) {
      try {
        _drawProcessor.call();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  //@Override
  public void surfaceChanged(SurfaceHolder holder, int format, 
      int width, int height) {
    // empty
  }

  //@Override
  public void surfaceCreated(SurfaceHolder holder) {
   _surfaceIsAvailable = true;
  }

  //@Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    _surfaceIsAvailable = false;
  }
}
